//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2024 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
@_spi(SotoInternal) import SotoCore

extension SecurityIR {
    // MARK: Enums

    public enum AwsRegion: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case afSouth1 = "af-south-1"
        case apEast1 = "ap-east-1"
        case apNortheast1 = "ap-northeast-1"
        case apNortheast2 = "ap-northeast-2"
        case apNortheast3 = "ap-northeast-3"
        case apSouth1 = "ap-south-1"
        case apSouth2 = "ap-south-2"
        case apSoutheast1 = "ap-southeast-1"
        case apSoutheast2 = "ap-southeast-2"
        case apSoutheast3 = "ap-southeast-3"
        case apSoutheast4 = "ap-southeast-4"
        case apSoutheast5 = "ap-southeast-5"
        case apSoutheast7 = "ap-southeast-7"
        case caCentral1 = "ca-central-1"
        case caWest1 = "ca-west-1"
        case cnNorth1 = "cn-north-1"
        case cnNorthwest1 = "cn-northwest-1"
        case euCentral1 = "eu-central-1"
        case euCentral2 = "eu-central-2"
        case euNorth1 = "eu-north-1"
        case euSouth1 = "eu-south-1"
        case euSouth2 = "eu-south-2"
        case euWest1 = "eu-west-1"
        case euWest2 = "eu-west-2"
        case euWest3 = "eu-west-3"
        case ilCentral1 = "il-central-1"
        case meCentral1 = "me-central-1"
        case meSouth1 = "me-south-1"
        case mxCentral1 = "mx-central-1"
        case saEast1 = "sa-east-1"
        case usEast1 = "us-east-1"
        case usEast2 = "us-east-2"
        case usWest1 = "us-west-1"
        case usWest2 = "us-west-2"
        public var description: String { return self.rawValue }
    }

    public enum CaseAttachmentStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case failed = "Failed"
        case pending = "Pending"
        case verified = "Verified"
        public var description: String { return self.rawValue }
    }

    public enum CaseStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case acknowledged = "Acknowledged"
        case closed = "Closed"
        case containmentEradicationAndRecovery = "Containment, Eradication and Recovery"
        case detectionAndAnalysis = "Detection and Analysis"
        case postIncidentActivities = "Post-incident Activities"
        case readyToClose = "Ready to Close"
        case submitted = "Submitted"
        public var description: String { return self.rawValue }
    }

    public enum ClosureCode: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case duplicate = "Duplicate"
        case falsePositive = "False Positive"
        case investigationCompleted = "Investigation Completed"
        case notResolved = "Not Resolved"
        public var description: String { return self.rawValue }
    }

    public enum CustomerType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case organization = "Organization"
        case standalone = "Standalone"
        public var description: String { return self.rawValue }
    }

    public enum EngagementType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case investigation = "Investigation"
        case securityIncident = "Security Incident"
        public var description: String { return self.rawValue }
    }

    public enum MembershipAccountRelationshipStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case associated = "Associated"
        case disassociated = "Disassociated"
        public var description: String { return self.rawValue }
    }

    public enum MembershipAccountRelationshipType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case organization = "Organization"
        public var description: String { return self.rawValue }
    }

    public enum MembershipStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case active = "Active"
        case cancelled = "Cancelled"
        case terminated = "Terminated"
        public var description: String { return self.rawValue }
    }

    public enum OptInFeatureName: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case triage = "Triage"
        public var description: String { return self.rawValue }
    }

    public enum PendingAction: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case customer = "Customer"
        case none = "None"
        public var description: String { return self.rawValue }
    }

    public enum ResolverType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case _self = "Self"
        case aws = "AWS"
        public var description: String { return self.rawValue }
    }

    public enum SelfManagedCaseStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case containmentEradicationAndRecovery = "Containment, Eradication and Recovery"
        case detectionAndAnalysis = "Detection and Analysis"
        case postIncidentActivities = "Post-incident Activities"
        case submitted = "Submitted"
        public var description: String { return self.rawValue }
    }

    public enum ValidationExceptionReason: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case cannotParse = "CANNOT_PARSE"
        case fieldValidationFailed = "FIELD_VALIDATION_FAILED"
        case other = "OTHER"
        case unknownOperation = "UNKNOWN_OPERATION"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct BatchGetMemberAccountDetailsRequest: AWSEncodableShape {
        /// Optional element to query the membership relationship status to a provided list of account IDs.
        public let accountIds: [String]
        /// Required element used in combination with BatchGetMemberAccountDetails to identify the membership ID to query.
        public let membershipId: String

        @inlinable
        public init(accountIds: [String], membershipId: String) {
            self.accountIds = accountIds
            self.membershipId = membershipId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encode(self.accountIds, forKey: .accountIds)
            request.encodePath(self.membershipId, key: "membershipId")
        }

        public func validate(name: String) throws {
            try self.accountIds.forEach {
                try validate($0, name: "accountIds[]", parent: name, max: 12)
                try validate($0, name: "accountIds[]", parent: name, min: 12)
                try validate($0, name: "accountIds[]", parent: name, pattern: "^[0-9]{12}$")
            }
            try self.validate(self.accountIds, name: "accountIds", parent: name, max: 100)
            try self.validate(self.accountIds, name: "accountIds", parent: name, min: 1)
            try self.validate(self.membershipId, name: "membershipId", parent: name, max: 34)
            try self.validate(self.membershipId, name: "membershipId", parent: name, min: 12)
            try self.validate(self.membershipId, name: "membershipId", parent: name, pattern: "^m-[a-z0-9]{10,32}$")
        }

        private enum CodingKeys: String, CodingKey {
            case accountIds = "accountIds"
        }
    }

    public struct BatchGetMemberAccountDetailsResponse: AWSDecodableShape {
        /// The response element providing errors messages for requests to GetMembershipAccountDetails.
        public let errors: [GetMembershipAccountDetailError]?
        /// The response element providing responses for requests to GetMembershipAccountDetails.
        public let items: [GetMembershipAccountDetailItem]?

        @inlinable
        public init(errors: [GetMembershipAccountDetailError]? = nil, items: [GetMembershipAccountDetailItem]? = nil) {
            self.errors = errors
            self.items = items
        }

        private enum CodingKeys: String, CodingKey {
            case errors = "errors"
            case items = "items"
        }
    }

    public struct CancelMembershipRequest: AWSEncodableShape {
        /// Required element used in combination with CancelMembershipRequest to identify the membership ID to cancel.
        public let membershipId: String

        @inlinable
        public init(membershipId: String) {
            self.membershipId = membershipId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.membershipId, key: "membershipId")
        }

        public func validate(name: String) throws {
            try self.validate(self.membershipId, name: "membershipId", parent: name, max: 34)
            try self.validate(self.membershipId, name: "membershipId", parent: name, min: 12)
            try self.validate(self.membershipId, name: "membershipId", parent: name, pattern: "^m-[a-z0-9]{10,32}$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct CancelMembershipResponse: AWSDecodableShape {
        /// The response element providing responses for requests to CancelMembershipRequest.
        public let membershipId: String

        @inlinable
        public init(membershipId: String) {
            self.membershipId = membershipId
        }

        private enum CodingKeys: String, CodingKey {
            case membershipId = "membershipId"
        }
    }

    public struct CaseAttachmentAttributes: AWSDecodableShape {
        public let attachmentId: String
        public let attachmentStatus: CaseAttachmentStatus
        public let createdDate: Date
        public let creator: String
        public let fileName: String

        @inlinable
        public init(attachmentId: String, attachmentStatus: CaseAttachmentStatus, createdDate: Date, creator: String, fileName: String) {
            self.attachmentId = attachmentId
            self.attachmentStatus = attachmentStatus
            self.createdDate = createdDate
            self.creator = creator
            self.fileName = fileName
        }

        private enum CodingKeys: String, CodingKey {
            case attachmentId = "attachmentId"
            case attachmentStatus = "attachmentStatus"
            case createdDate = "createdDate"
            case creator = "creator"
            case fileName = "fileName"
        }
    }

    public struct CaseEditItem: AWSDecodableShape {
        public let action: String?
        public let eventTimestamp: Date?
        public let message: String?
        public let principal: String?

        @inlinable
        public init(action: String? = nil, eventTimestamp: Date? = nil, message: String? = nil, principal: String? = nil) {
            self.action = action
            self.eventTimestamp = eventTimestamp
            self.message = message
            self.principal = principal
        }

        private enum CodingKeys: String, CodingKey {
            case action = "action"
            case eventTimestamp = "eventTimestamp"
            case message = "message"
            case principal = "principal"
        }
    }

    public struct CloseCaseRequest: AWSEncodableShape {
        /// Required element used in combination with CloseCase to identify the case ID to close.
        public let caseId: String

        @inlinable
        public init(caseId: String) {
            self.caseId = caseId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.caseId, key: "caseId")
        }

        public func validate(name: String) throws {
            try self.validate(self.caseId, name: "caseId", parent: name, max: 32)
            try self.validate(self.caseId, name: "caseId", parent: name, min: 10)
            try self.validate(self.caseId, name: "caseId", parent: name, pattern: "^\\d{10,32}")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct CloseCaseResponse: AWSDecodableShape {
        /// A response element providing responses for requests to CloseCase. This element responds with the case status following the action.
        public let caseStatus: CaseStatus?
        /// A response element providing responses for requests to CloseCase. This element responds with the case closure date following the action.
        public let closedDate: Date?

        @inlinable
        public init(caseStatus: CaseStatus? = nil, closedDate: Date? = nil) {
            self.caseStatus = caseStatus
            self.closedDate = closedDate
        }

        private enum CodingKeys: String, CodingKey {
            case caseStatus = "caseStatus"
            case closedDate = "closedDate"
        }
    }

    public struct CreateCaseCommentRequest: AWSEncodableShape {
        /// Required element used in combination with CreateCaseComment to add content for the new comment.
        public let body: String
        /// Required element used in combination with CreateCaseComment to specify a case ID.
        public let caseId: String
        /// An optional element used in combination with CreateCaseComment.
        public let clientToken: String?

        @inlinable
        public init(body: String, caseId: String, clientToken: String? = nil) {
            self.body = body
            self.caseId = caseId
            self.clientToken = clientToken
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encode(self.body, forKey: .body)
            request.encodePath(self.caseId, key: "caseId")
            try container.encodeIfPresent(self.clientToken, forKey: .clientToken)
        }

        public func validate(name: String) throws {
            try self.validate(self.body, name: "body", parent: name, max: 12000)
            try self.validate(self.body, name: "body", parent: name, min: 1)
            try self.validate(self.caseId, name: "caseId", parent: name, max: 32)
            try self.validate(self.caseId, name: "caseId", parent: name, min: 10)
            try self.validate(self.caseId, name: "caseId", parent: name, pattern: "^\\d{10,32}")
        }

        private enum CodingKeys: String, CodingKey {
            case body = "body"
            case clientToken = "clientToken"
        }
    }

    public struct CreateCaseCommentResponse: AWSDecodableShape {
        /// Response element indicating the new comment ID.
        public let commentId: String

        @inlinable
        public init(commentId: String) {
            self.commentId = commentId
        }

        private enum CodingKeys: String, CodingKey {
            case commentId = "commentId"
        }
    }

    public struct CreateCaseRequest: AWSEncodableShape {
        /// Required element used in combination with CreateCase.
        public let clientToken: String?
        /// Required element used in combination with CreateCase to provide a description for the new case.
        public let description: String
        /// Required element used in combination with CreateCase to provide an engagement type for the new cases. Available engagement types include Security Incident | Investigation
        public let engagementType: EngagementType
        /// Required element used in combination with CreateCase to provide a list of impacted accounts.
        public let impactedAccounts: [String]
        /// An optional element used in combination with CreateCase to provide a list of impacted regions.
        public let impactedAwsRegions: [ImpactedAwsRegion]?
        /// An optional element used in combination with CreateCase to provide a list of services impacted.
        public let impactedServices: [String]?
        /// Required element used in combination with CreateCase to provide an initial start date for the unauthorized activity.
        public let reportedIncidentStartDate: Date
        /// Required element used in combination with CreateCase to identify the resolver type. Available resolvers include self-supported | aws-supported.
        public let resolverType: ResolverType
        /// An optional element used in combination with CreateCase to add customer specified tags to a case.
        public let tags: [String: String]?
        /// An optional element used in combination with CreateCase to provide a list of suspicious internet protocol addresses associated with unauthorized activity.
        public let threatActorIpAddresses: [ThreatActorIp]?
        /// Required element used in combination with CreateCase to provide a title for the new case.
        public let title: String
        /// Required element used in combination with CreateCase to provide a list of entities to receive notifications for case updates.
        public let watchers: [Watcher]

        @inlinable
        public init(clientToken: String? = nil, description: String, engagementType: EngagementType, impactedAccounts: [String], impactedAwsRegions: [ImpactedAwsRegion]? = nil, impactedServices: [String]? = nil, reportedIncidentStartDate: Date, resolverType: ResolverType, tags: [String: String]? = nil, threatActorIpAddresses: [ThreatActorIp]? = nil, title: String, watchers: [Watcher]) {
            self.clientToken = clientToken
            self.description = description
            self.engagementType = engagementType
            self.impactedAccounts = impactedAccounts
            self.impactedAwsRegions = impactedAwsRegions
            self.impactedServices = impactedServices
            self.reportedIncidentStartDate = reportedIncidentStartDate
            self.resolverType = resolverType
            self.tags = tags
            self.threatActorIpAddresses = threatActorIpAddresses
            self.title = title
            self.watchers = watchers
        }

        public func validate(name: String) throws {
            try self.validate(self.description, name: "description", parent: name, max: 8000)
            try self.validate(self.description, name: "description", parent: name, min: 1)
            try self.impactedAccounts.forEach {
                try validate($0, name: "impactedAccounts[]", parent: name, max: 12)
                try validate($0, name: "impactedAccounts[]", parent: name, min: 12)
                try validate($0, name: "impactedAccounts[]", parent: name, pattern: "^[0-9]{12}$")
            }
            try self.validate(self.impactedAccounts, name: "impactedAccounts", parent: name, max: 200)
            try self.validate(self.impactedAwsRegions, name: "impactedAwsRegions", parent: name, max: 50)
            try self.impactedServices?.forEach {
                try validate($0, name: "impactedServices[]", parent: name, max: 50)
                try validate($0, name: "impactedServices[]", parent: name, min: 3)
                try validate($0, name: "impactedServices[]", parent: name, pattern: "^[a-zA-Z0-9 -.():]+$")
            }
            try self.validate(self.impactedServices, name: "impactedServices", parent: name, max: 600)
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
            try self.threatActorIpAddresses?.forEach {
                try $0.validate(name: "\(name).threatActorIpAddresses[]")
            }
            try self.validate(self.threatActorIpAddresses, name: "threatActorIpAddresses", parent: name, max: 200)
            try self.validate(self.title, name: "title", parent: name, max: 300)
            try self.validate(self.title, name: "title", parent: name, min: 1)
            try self.watchers.forEach {
                try $0.validate(name: "\(name).watchers[]")
            }
            try self.validate(self.watchers, name: "watchers", parent: name, max: 30)
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken = "clientToken"
            case description = "description"
            case engagementType = "engagementType"
            case impactedAccounts = "impactedAccounts"
            case impactedAwsRegions = "impactedAwsRegions"
            case impactedServices = "impactedServices"
            case reportedIncidentStartDate = "reportedIncidentStartDate"
            case resolverType = "resolverType"
            case tags = "tags"
            case threatActorIpAddresses = "threatActorIpAddresses"
            case title = "title"
            case watchers = "watchers"
        }
    }

    public struct CreateCaseResponse: AWSDecodableShape {
        /// A response element providing responses for requests to CreateCase. This element responds with the case ID.
        public let caseId: String

        @inlinable
        public init(caseId: String) {
            self.caseId = caseId
        }

        private enum CodingKeys: String, CodingKey {
            case caseId = "caseId"
        }
    }

    public struct CreateMembershipRequest: AWSEncodableShape {
        /// An optional element used in combination with CreateMembership.
        public let clientToken: String?
        /// Required element use in combination with CreateMembership to add customer incident response team members and trusted partners to the membership.
        public let incidentResponseTeam: [IncidentResponder]
        /// Required element use in combination with CreateMembership to create a name for the membership.
        public let membershipName: String
        /// Optional element to enable the monitoring and investigation opt-in features for the service.
        public let optInFeatures: [OptInFeature]?
        /// Optional element for customer configured tags.
        public let tags: [String: String]?

        @inlinable
        public init(clientToken: String? = nil, incidentResponseTeam: [IncidentResponder], membershipName: String, optInFeatures: [OptInFeature]? = nil, tags: [String: String]? = nil) {
            self.clientToken = clientToken
            self.incidentResponseTeam = incidentResponseTeam
            self.membershipName = membershipName
            self.optInFeatures = optInFeatures
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.incidentResponseTeam.forEach {
                try $0.validate(name: "\(name).incidentResponseTeam[]")
            }
            try self.validate(self.incidentResponseTeam, name: "incidentResponseTeam", parent: name, max: 10)
            try self.validate(self.incidentResponseTeam, name: "incidentResponseTeam", parent: name, min: 2)
            try self.validate(self.membershipName, name: "membershipName", parent: name, max: 50)
            try self.validate(self.membershipName, name: "membershipName", parent: name, min: 3)
            try self.validate(self.optInFeatures, name: "optInFeatures", parent: name, max: 2)
            try self.validate(self.optInFeatures, name: "optInFeatures", parent: name, min: 1)
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken = "clientToken"
            case incidentResponseTeam = "incidentResponseTeam"
            case membershipName = "membershipName"
            case optInFeatures = "optInFeatures"
            case tags = "tags"
        }
    }

    public struct CreateMembershipResponse: AWSDecodableShape {
        /// Response element for CreateMembership providing the newly created membership ID.
        public let membershipId: String

        @inlinable
        public init(membershipId: String) {
            self.membershipId = membershipId
        }

        private enum CodingKeys: String, CodingKey {
            case membershipId = "membershipId"
        }
    }

    public struct GetCaseAttachmentDownloadUrlRequest: AWSEncodableShape {
        /// Required element for GetCaseAttachmentDownloadUrl to identify the attachment ID for downloading an attachment.
        public let attachmentId: String
        /// Required element for GetCaseAttachmentDownloadUrl to identify the case ID for downloading an attachment from.
        public let caseId: String

        @inlinable
        public init(attachmentId: String, caseId: String) {
            self.attachmentId = attachmentId
            self.caseId = caseId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.attachmentId, key: "attachmentId")
            request.encodePath(self.caseId, key: "caseId")
        }

        public func validate(name: String) throws {
            try self.validate(self.attachmentId, name: "attachmentId", parent: name, pattern: "^[0-9a-fA-F]{8}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{12}$")
            try self.validate(self.caseId, name: "caseId", parent: name, max: 32)
            try self.validate(self.caseId, name: "caseId", parent: name, min: 10)
            try self.validate(self.caseId, name: "caseId", parent: name, pattern: "^\\d{10,32}")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetCaseAttachmentDownloadUrlResponse: AWSDecodableShape {
        /// Response element providing the Amazon S3 presigned URL to download an attachment.
        public let attachmentPresignedUrl: String

        @inlinable
        public init(attachmentPresignedUrl: String) {
            self.attachmentPresignedUrl = attachmentPresignedUrl
        }

        private enum CodingKeys: String, CodingKey {
            case attachmentPresignedUrl = "attachmentPresignedUrl"
        }
    }

    public struct GetCaseAttachmentUploadUrlRequest: AWSEncodableShape {
        /// Required element for GetCaseAttachmentUploadUrl to identify the case ID for uploading an attachment to.
        public let caseId: String
        /// Optional element for customer provided token.
        public let clientToken: String?
        /// Required element for GetCaseAttachmentUploadUrl to identify the size od the file attachment.
        public let contentLength: Int64
        /// Required element for GetCaseAttachmentUploadUrl to identify the file name of the attachment to upload.
        public let fileName: String

        @inlinable
        public init(caseId: String, clientToken: String? = nil, contentLength: Int64, fileName: String) {
            self.caseId = caseId
            self.clientToken = clientToken
            self.contentLength = contentLength
            self.fileName = fileName
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.caseId, key: "caseId")
            try container.encodeIfPresent(self.clientToken, forKey: .clientToken)
            try container.encode(self.contentLength, forKey: .contentLength)
            try container.encode(self.fileName, forKey: .fileName)
        }

        public func validate(name: String) throws {
            try self.validate(self.caseId, name: "caseId", parent: name, max: 32)
            try self.validate(self.caseId, name: "caseId", parent: name, min: 10)
            try self.validate(self.caseId, name: "caseId", parent: name, pattern: "^\\d{10,32}")
            try self.validate(self.contentLength, name: "contentLength", parent: name, max: 104857600)
            try self.validate(self.contentLength, name: "contentLength", parent: name, min: 1)
            try self.validate(self.fileName, name: "fileName", parent: name, max: 255)
            try self.validate(self.fileName, name: "fileName", parent: name, min: 1)
            try self.validate(self.fileName, name: "fileName", parent: name, pattern: "^[a-zA-Z0-9._-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken = "clientToken"
            case contentLength = "contentLength"
            case fileName = "fileName"
        }
    }

    public struct GetCaseAttachmentUploadUrlResponse: AWSDecodableShape {
        /// Response element providing the Amazon S3 presigned UTL to upload the attachment.
        public let attachmentPresignedUrl: String

        @inlinable
        public init(attachmentPresignedUrl: String) {
            self.attachmentPresignedUrl = attachmentPresignedUrl
        }

        private enum CodingKeys: String, CodingKey {
            case attachmentPresignedUrl = "attachmentPresignedUrl"
        }
    }

    public struct GetCaseRequest: AWSEncodableShape {
        /// Required element for GetCase to identify the requested case ID.
        public let caseId: String

        @inlinable
        public init(caseId: String) {
            self.caseId = caseId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.caseId, key: "caseId")
        }

        public func validate(name: String) throws {
            try self.validate(self.caseId, name: "caseId", parent: name, max: 32)
            try self.validate(self.caseId, name: "caseId", parent: name, min: 10)
            try self.validate(self.caseId, name: "caseId", parent: name, pattern: "^\\d{10,32}")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetCaseResponse: AWSDecodableShape {
        /// Response element for GetCase that provides the actual incident start date as identified by data analysis during the investigation.
        public let actualIncidentStartDate: Date?
        /// Response element for GetCase that provides the case ARN
        public let caseArn: String?
        /// Response element for GetCase that provides a list of current case attachments.
        public let caseAttachments: [CaseAttachmentAttributes]?
        /// Response element for GetCase that provides the case status. Options for statuses include Submitted | Detection and Analysis | Eradication, Containment and Recovery | Post-Incident Activities | Closed
        public let caseStatus: CaseStatus?
        /// Response element for GetCase that provides the date a specified case was closed.
        public let closedDate: Date?
        /// Response element for GetCase that provides the summary code for why a case was closed.
        public let closureCode: ClosureCode?
        /// Response element for GetCase that provides the date the case was created.
        public let createdDate: Date?
        /// Response element for GetCase that provides contents of the case description.
        public let description: String?
        /// Response element for GetCase that provides the engagement type. Options for engagement type include Active Security Event | Investigations
        public let engagementType: EngagementType?
        /// Response element for GetCase that provides a list of impacted accounts.
        public let impactedAccounts: [String]?
        /// Response element for GetCase that provides the impacted regions.
        public let impactedAwsRegions: [ImpactedAwsRegion]?
        /// Response element for GetCase that provides a list of impacted services.
        public let impactedServices: [String]?
        /// Response element for GetCase that provides the date a case was last modified.
        public let lastUpdatedDate: Date?
        /// Response element for GetCase that provides identifies the case is waiting on customer input.
        public let pendingAction: PendingAction?
        /// Response element for GetCase that provides the customer provided incident start date.
        public let reportedIncidentStartDate: Date?
        /// Response element for GetCase that provides the current resolver types. Options include  self-supported | AWS-supported.
        public let resolverType: ResolverType?
        /// Response element for GetCase that provides a list of suspicious IP addresses associated with unauthorized activity.
        public let threatActorIpAddresses: [ThreatActorIp]?
        /// Response element for GetCase that provides the case title.
        public let title: String?
        /// Response element for GetCase that provides a list of Watchers added to the case.
        public let watchers: [Watcher]?

        @inlinable
        public init(actualIncidentStartDate: Date? = nil, caseArn: String? = nil, caseAttachments: [CaseAttachmentAttributes]? = nil, caseStatus: CaseStatus? = nil, closedDate: Date? = nil, closureCode: ClosureCode? = nil, createdDate: Date? = nil, description: String? = nil, engagementType: EngagementType? = nil, impactedAccounts: [String]? = nil, impactedAwsRegions: [ImpactedAwsRegion]? = nil, impactedServices: [String]? = nil, lastUpdatedDate: Date? = nil, pendingAction: PendingAction? = nil, reportedIncidentStartDate: Date? = nil, resolverType: ResolverType? = nil, threatActorIpAddresses: [ThreatActorIp]? = nil, title: String? = nil, watchers: [Watcher]? = nil) {
            self.actualIncidentStartDate = actualIncidentStartDate
            self.caseArn = caseArn
            self.caseAttachments = caseAttachments
            self.caseStatus = caseStatus
            self.closedDate = closedDate
            self.closureCode = closureCode
            self.createdDate = createdDate
            self.description = description
            self.engagementType = engagementType
            self.impactedAccounts = impactedAccounts
            self.impactedAwsRegions = impactedAwsRegions
            self.impactedServices = impactedServices
            self.lastUpdatedDate = lastUpdatedDate
            self.pendingAction = pendingAction
            self.reportedIncidentStartDate = reportedIncidentStartDate
            self.resolverType = resolverType
            self.threatActorIpAddresses = threatActorIpAddresses
            self.title = title
            self.watchers = watchers
        }

        private enum CodingKeys: String, CodingKey {
            case actualIncidentStartDate = "actualIncidentStartDate"
            case caseArn = "caseArn"
            case caseAttachments = "caseAttachments"
            case caseStatus = "caseStatus"
            case closedDate = "closedDate"
            case closureCode = "closureCode"
            case createdDate = "createdDate"
            case description = "description"
            case engagementType = "engagementType"
            case impactedAccounts = "impactedAccounts"
            case impactedAwsRegions = "impactedAwsRegions"
            case impactedServices = "impactedServices"
            case lastUpdatedDate = "lastUpdatedDate"
            case pendingAction = "pendingAction"
            case reportedIncidentStartDate = "reportedIncidentStartDate"
            case resolverType = "resolverType"
            case threatActorIpAddresses = "threatActorIpAddresses"
            case title = "title"
            case watchers = "watchers"
        }
    }

    public struct GetMembershipAccountDetailError: AWSDecodableShape {
        public let accountId: String
        public let error: String
        public let message: String

        @inlinable
        public init(accountId: String, error: String, message: String) {
            self.accountId = accountId
            self.error = error
            self.message = message
        }

        private enum CodingKeys: String, CodingKey {
            case accountId = "accountId"
            case error = "error"
            case message = "message"
        }
    }

    public struct GetMembershipAccountDetailItem: AWSDecodableShape {
        public let accountId: String?
        public let relationshipStatus: MembershipAccountRelationshipStatus?
        public let relationshipType: MembershipAccountRelationshipType?

        @inlinable
        public init(accountId: String? = nil, relationshipStatus: MembershipAccountRelationshipStatus? = nil, relationshipType: MembershipAccountRelationshipType? = nil) {
            self.accountId = accountId
            self.relationshipStatus = relationshipStatus
            self.relationshipType = relationshipType
        }

        private enum CodingKeys: String, CodingKey {
            case accountId = "accountId"
            case relationshipStatus = "relationshipStatus"
            case relationshipType = "relationshipType"
        }
    }

    public struct GetMembershipRequest: AWSEncodableShape {
        /// Required element for GetMembership to identify the membership ID to query.
        public let membershipId: String

        @inlinable
        public init(membershipId: String) {
            self.membershipId = membershipId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.membershipId, key: "membershipId")
        }

        public func validate(name: String) throws {
            try self.validate(self.membershipId, name: "membershipId", parent: name, max: 34)
            try self.validate(self.membershipId, name: "membershipId", parent: name, min: 12)
            try self.validate(self.membershipId, name: "membershipId", parent: name, pattern: "^m-[a-z0-9]{10,32}$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetMembershipResponse: AWSDecodableShape {
        /// Response element for GetMembership that provides the configured account for managing the membership.
        public let accountId: String?
        /// Response element for GetMembership that provides the configured membership type. Options include  Standalone | Organizations.
        public let customerType: CustomerType?
        /// Response element for GetMembership that provides the configured membership incident response team members.
        public let incidentResponseTeam: [IncidentResponder]?
        /// Response element for GetMembership that provides the configured membership activation timestamp.
        public let membershipActivationTimestamp: Date?
        /// Response element for GetMembership that provides the membership ARN.
        public let membershipArn: String?
        /// Response element for GetMembership that provides the configured membership name deactivation timestamp.
        public let membershipDeactivationTimestamp: Date?
        /// Response element for GetMembership that provides the queried membership ID.
        public let membershipId: String
        /// Response element for GetMembership that provides the configured membership name.
        public let membershipName: String?
        /// Response element for GetMembership that provides the current membership status.
        public let membershipStatus: MembershipStatus?
        /// Response element for GetMembership that provides the number of accounts in the membership.
        public let numberOfAccountsCovered: Int64?
        /// Response element for GetMembership that provides the if opt-in features have been enabled.
        public let optInFeatures: [OptInFeature]?
        /// Response element for GetMembership that provides the configured region for managing the membership.
        public let region: AwsRegion?

        @inlinable
        public init(accountId: String? = nil, customerType: CustomerType? = nil, incidentResponseTeam: [IncidentResponder]? = nil, membershipActivationTimestamp: Date? = nil, membershipArn: String? = nil, membershipDeactivationTimestamp: Date? = nil, membershipId: String, membershipName: String? = nil, membershipStatus: MembershipStatus? = nil, numberOfAccountsCovered: Int64? = nil, optInFeatures: [OptInFeature]? = nil, region: AwsRegion? = nil) {
            self.accountId = accountId
            self.customerType = customerType
            self.incidentResponseTeam = incidentResponseTeam
            self.membershipActivationTimestamp = membershipActivationTimestamp
            self.membershipArn = membershipArn
            self.membershipDeactivationTimestamp = membershipDeactivationTimestamp
            self.membershipId = membershipId
            self.membershipName = membershipName
            self.membershipStatus = membershipStatus
            self.numberOfAccountsCovered = numberOfAccountsCovered
            self.optInFeatures = optInFeatures
            self.region = region
        }

        private enum CodingKeys: String, CodingKey {
            case accountId = "accountId"
            case customerType = "customerType"
            case incidentResponseTeam = "incidentResponseTeam"
            case membershipActivationTimestamp = "membershipActivationTimestamp"
            case membershipArn = "membershipArn"
            case membershipDeactivationTimestamp = "membershipDeactivationTimestamp"
            case membershipId = "membershipId"
            case membershipName = "membershipName"
            case membershipStatus = "membershipStatus"
            case numberOfAccountsCovered = "numberOfAccountsCovered"
            case optInFeatures = "optInFeatures"
            case region = "region"
        }
    }

    public struct ImpactedAwsRegion: AWSEncodableShape & AWSDecodableShape {
        public let region: AwsRegion

        @inlinable
        public init(region: AwsRegion) {
            self.region = region
        }

        private enum CodingKeys: String, CodingKey {
            case region = "region"
        }
    }

    public struct IncidentResponder: AWSEncodableShape & AWSDecodableShape {
        public let email: String
        public let jobTitle: String
        public let name: String

        @inlinable
        public init(email: String, jobTitle: String, name: String) {
            self.email = email
            self.jobTitle = jobTitle
            self.name = name
        }

        public func validate(name: String) throws {
            try self.validate(self.email, name: "email", parent: name, max: 254)
            try self.validate(self.email, name: "email", parent: name, min: 6)
            try self.validate(self.email, name: "email", parent: name, pattern: "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$")
            try self.validate(self.jobTitle, name: "jobTitle", parent: name, max: 50)
            try self.validate(self.jobTitle, name: "jobTitle", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, max: 50)
            try self.validate(self.name, name: "name", parent: name, min: 3)
        }

        private enum CodingKeys: String, CodingKey {
            case email = "email"
            case jobTitle = "jobTitle"
            case name = "name"
        }
    }

    public struct ListCaseEditsRequest: AWSEncodableShape {
        /// Required element used with ListCaseEdits to identify the case to query.
        public let caseId: String
        /// Optional element to identify how many results to obtain. There is a maximum value of 25.
        public let maxResults: Int?
        /// Optional element for a customer provided token.
        public let nextToken: String?

        @inlinable
        public init(caseId: String, maxResults: Int? = nil, nextToken: String? = nil) {
            self.caseId = caseId
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.caseId, key: "caseId")
            try container.encodeIfPresent(self.maxResults, forKey: .maxResults)
            try container.encodeIfPresent(self.nextToken, forKey: .nextToken)
        }

        public func validate(name: String) throws {
            try self.validate(self.caseId, name: "caseId", parent: name, max: 32)
            try self.validate(self.caseId, name: "caseId", parent: name, min: 10)
            try self.validate(self.caseId, name: "caseId", parent: name, pattern: "^\\d{10,32}")
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "maxResults"
            case nextToken = "nextToken"
        }
    }

    public struct ListCaseEditsResponse: AWSDecodableShape {
        /// Response element for ListCaseEdits that includes the action, eventtimestamp, message, and principal for the response.
        public let items: [CaseEditItem]?
        /// Optional element.
        public let nextToken: String?
        /// Response element for ListCaseEdits that identifies the total number of edits.
        public let total: Int?

        @inlinable
        public init(items: [CaseEditItem]? = nil, nextToken: String? = nil, total: Int? = nil) {
            self.items = items
            self.nextToken = nextToken
            self.total = total
        }

        private enum CodingKeys: String, CodingKey {
            case items = "items"
            case nextToken = "nextToken"
            case total = "total"
        }
    }

    public struct ListCasesItem: AWSDecodableShape {
        public let caseArn: String?
        public let caseId: String
        public let caseStatus: CaseStatus?
        public let closedDate: Date?
        public let createdDate: Date?
        public let engagementType: EngagementType?
        public let lastUpdatedDate: Date?
        public let pendingAction: PendingAction?
        public let resolverType: ResolverType?
        public let title: String?

        @inlinable
        public init(caseArn: String? = nil, caseId: String, caseStatus: CaseStatus? = nil, closedDate: Date? = nil, createdDate: Date? = nil, engagementType: EngagementType? = nil, lastUpdatedDate: Date? = nil, pendingAction: PendingAction? = nil, resolverType: ResolverType? = nil, title: String? = nil) {
            self.caseArn = caseArn
            self.caseId = caseId
            self.caseStatus = caseStatus
            self.closedDate = closedDate
            self.createdDate = createdDate
            self.engagementType = engagementType
            self.lastUpdatedDate = lastUpdatedDate
            self.pendingAction = pendingAction
            self.resolverType = resolverType
            self.title = title
        }

        private enum CodingKeys: String, CodingKey {
            case caseArn = "caseArn"
            case caseId = "caseId"
            case caseStatus = "caseStatus"
            case closedDate = "closedDate"
            case createdDate = "createdDate"
            case engagementType = "engagementType"
            case lastUpdatedDate = "lastUpdatedDate"
            case pendingAction = "pendingAction"
            case resolverType = "resolverType"
            case title = "title"
        }
    }

    public struct ListCasesRequest: AWSEncodableShape {
        /// Optional element for ListCases to limit the number of responses.
        public let maxResults: Int?
        /// Optional element.
        public let nextToken: String?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "maxResults"
            case nextToken = "nextToken"
        }
    }

    public struct ListCasesResponse: AWSDecodableShape {
        /// Response element for ListCases that includes caseARN, caseID, caseStatus, closedDate, createdDate, engagementType, lastUpdatedDate, pendingAction, resolverType, and title for each response.
        public let items: [ListCasesItem]?
        /// Optional element.
        public let nextToken: String?
        /// Response element for ListCases providing the total number of responses.
        public let total: Int64?

        @inlinable
        public init(items: [ListCasesItem]? = nil, nextToken: String? = nil, total: Int64? = nil) {
            self.items = items
            self.nextToken = nextToken
            self.total = total
        }

        private enum CodingKeys: String, CodingKey {
            case items = "items"
            case nextToken = "nextToken"
            case total = "total"
        }
    }

    public struct ListCommentsItem: AWSDecodableShape {
        public let body: String?
        public let commentId: String
        public let createdDate: Date?
        public let creator: String?
        public let lastUpdatedBy: String?
        public let lastUpdatedDate: Date?

        @inlinable
        public init(body: String? = nil, commentId: String, createdDate: Date? = nil, creator: String? = nil, lastUpdatedBy: String? = nil, lastUpdatedDate: Date? = nil) {
            self.body = body
            self.commentId = commentId
            self.createdDate = createdDate
            self.creator = creator
            self.lastUpdatedBy = lastUpdatedBy
            self.lastUpdatedDate = lastUpdatedDate
        }

        private enum CodingKeys: String, CodingKey {
            case body = "body"
            case commentId = "commentId"
            case createdDate = "createdDate"
            case creator = "creator"
            case lastUpdatedBy = "lastUpdatedBy"
            case lastUpdatedDate = "lastUpdatedDate"
        }
    }

    public struct ListCommentsRequest: AWSEncodableShape {
        /// Required element for ListComments to designate the case to query.
        public let caseId: String
        /// Optional element for ListComments to limit the number of responses.
        public let maxResults: Int?
        /// Optional element.
        public let nextToken: String?

        @inlinable
        public init(caseId: String, maxResults: Int? = nil, nextToken: String? = nil) {
            self.caseId = caseId
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.caseId, key: "caseId")
            try container.encodeIfPresent(self.maxResults, forKey: .maxResults)
            try container.encodeIfPresent(self.nextToken, forKey: .nextToken)
        }

        public func validate(name: String) throws {
            try self.validate(self.caseId, name: "caseId", parent: name, max: 32)
            try self.validate(self.caseId, name: "caseId", parent: name, min: 10)
            try self.validate(self.caseId, name: "caseId", parent: name, pattern: "^\\d{10,32}")
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "maxResults"
            case nextToken = "nextToken"
        }
    }

    public struct ListCommentsResponse: AWSDecodableShape {
        /// Response element for ListComments providing the body, commentID, createDate, creator, lastUpdatedBy and lastUpdatedDate for each response.
        public let items: [ListCommentsItem]?
        /// Optional request elements.
        public let nextToken: String?
        /// Response element for ListComments identifying the number of responses.
        public let total: Int?

        @inlinable
        public init(items: [ListCommentsItem]? = nil, nextToken: String? = nil, total: Int? = nil) {
            self.items = items
            self.nextToken = nextToken
            self.total = total
        }

        private enum CodingKeys: String, CodingKey {
            case items = "items"
            case nextToken = "nextToken"
            case total = "total"
        }
    }

    public struct ListMembershipItem: AWSDecodableShape {
        public let accountId: String?
        public let membershipArn: String?
        public let membershipId: String
        public let membershipStatus: MembershipStatus?
        public let region: AwsRegion?

        @inlinable
        public init(accountId: String? = nil, membershipArn: String? = nil, membershipId: String, membershipStatus: MembershipStatus? = nil, region: AwsRegion? = nil) {
            self.accountId = accountId
            self.membershipArn = membershipArn
            self.membershipId = membershipId
            self.membershipStatus = membershipStatus
            self.region = region
        }

        private enum CodingKeys: String, CodingKey {
            case accountId = "accountId"
            case membershipArn = "membershipArn"
            case membershipId = "membershipId"
            case membershipStatus = "membershipStatus"
            case region = "region"
        }
    }

    public struct ListMembershipsRequest: AWSEncodableShape {
        /// Request element for ListMemberships to limit the number of responses.
        public let maxResults: Int?
        /// Optional element.
        public let nextToken: String?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "maxResults"
            case nextToken = "nextToken"
        }
    }

    public struct ListMembershipsResponse: AWSDecodableShape {
        /// Request element for ListMemberships including the accountID, membershipARN, membershipID, membershipStatus, and region for each response.
        public let items: [ListMembershipItem]?
        /// Optional element.
        public let nextToken: String?

        @inlinable
        public init(items: [ListMembershipItem]? = nil, nextToken: String? = nil) {
            self.items = items
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case items = "items"
            case nextToken = "nextToken"
        }
    }

    public struct ListTagsForResourceInput: AWSEncodableShape {
        /// Required element for ListTagsForResource to provide the ARN to identify a specific resource.
        public let resourceArn: String

        @inlinable
        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.resourceArn, key: "resourceArn")
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 1010)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 12)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws:security-ir:\\w+?-\\w+?-\\d+:[0-9]{12}:(membership/m-[a-z0-9]{10,32}|case/[0-9]{10})$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListTagsForResourceOutput: AWSDecodableShape {
        /// Response element for ListTagsForResource providing content for each configured tag.
        public let tags: [String: String]

        @inlinable
        public init(tags: [String: String]) {
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case tags = "tags"
        }
    }

    public struct OptInFeature: AWSEncodableShape & AWSDecodableShape {
        public let featureName: OptInFeatureName
        public let isEnabled: Bool

        @inlinable
        public init(featureName: OptInFeatureName, isEnabled: Bool) {
            self.featureName = featureName
            self.isEnabled = isEnabled
        }

        private enum CodingKeys: String, CodingKey {
            case featureName = "featureName"
            case isEnabled = "isEnabled"
        }
    }

    public struct TagResourceInput: AWSEncodableShape {
        /// Required element for TagResource to identify the ARN for the resource to add a tag to.
        public let resourceArn: String
        /// Required element for ListTagsForResource to provide the content for a tag.
        public let tags: [String: String]

        @inlinable
        public init(resourceArn: String, tags: [String: String]) {
            self.resourceArn = resourceArn
            self.tags = tags
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.resourceArn, key: "resourceArn")
            try container.encode(self.tags, forKey: .tags)
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 1010)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 12)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws:security-ir:\\w+?-\\w+?-\\d+:[0-9]{12}:(membership/m-[a-z0-9]{10,32}|case/[0-9]{10})$")
            try self.tags.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
        }

        private enum CodingKeys: String, CodingKey {
            case tags = "tags"
        }
    }

    public struct TagResourceOutput: AWSDecodableShape {
        public init() {}
    }

    public struct ThreatActorIp: AWSEncodableShape & AWSDecodableShape {
        public let ipAddress: String
        public let userAgent: String?

        @inlinable
        public init(ipAddress: String, userAgent: String? = nil) {
            self.ipAddress = ipAddress
            self.userAgent = userAgent
        }

        public func validate(name: String) throws {
            try self.validate(self.ipAddress, name: "ipAddress", parent: name, pattern: "^(?:(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))|(?:(?:[A-F0-9]{1,4}:){7}[A-F0-9]{1,4})|(?:(?:[A-F0-9]{1,4}:){6}(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))$")
            try self.validate(self.userAgent, name: "userAgent", parent: name, max: 500)
            try self.validate(self.userAgent, name: "userAgent", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case ipAddress = "ipAddress"
            case userAgent = "userAgent"
        }
    }

    public struct UntagResourceInput: AWSEncodableShape {
        /// Required element for UnTagResource to identify the ARN for the resource to remove a tag from.
        public let resourceArn: String
        /// Required element for UnTagResource to identify tag to remove.
        public let tagKeys: [String]

        @inlinable
        public init(resourceArn: String, tagKeys: [String]) {
            self.resourceArn = resourceArn
            self.tagKeys = tagKeys
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.resourceArn, key: "resourceArn")
            request.encodeQuery(self.tagKeys, key: "tagKeys")
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 1010)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 12)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws:security-ir:\\w+?-\\w+?-\\d+:[0-9]{12}:(membership/m-[a-z0-9]{10,32}|case/[0-9]{10})$")
            try self.tagKeys.forEach {
                try validate($0, name: "tagKeys[]", parent: name, max: 128)
                try validate($0, name: "tagKeys[]", parent: name, min: 1)
            }
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct UntagResourceOutput: AWSDecodableShape {
        public init() {}
    }

    public struct UpdateCaseCommentRequest: AWSEncodableShape {
        /// Required element for UpdateCaseComment to identify the content for the comment to be updated.
        public let body: String
        /// Required element for UpdateCaseComment to identify the case ID containing the comment to be updated.
        public let caseId: String
        /// Required element for UpdateCaseComment to identify the case ID to be updated.
        public let commentId: String

        @inlinable
        public init(body: String, caseId: String, commentId: String) {
            self.body = body
            self.caseId = caseId
            self.commentId = commentId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encode(self.body, forKey: .body)
            request.encodePath(self.caseId, key: "caseId")
            request.encodePath(self.commentId, key: "commentId")
        }

        public func validate(name: String) throws {
            try self.validate(self.body, name: "body", parent: name, max: 12000)
            try self.validate(self.body, name: "body", parent: name, min: 1)
            try self.validate(self.caseId, name: "caseId", parent: name, max: 32)
            try self.validate(self.caseId, name: "caseId", parent: name, min: 10)
            try self.validate(self.caseId, name: "caseId", parent: name, pattern: "^\\d{10,32}")
            try self.validate(self.commentId, name: "commentId", parent: name, max: 6)
            try self.validate(self.commentId, name: "commentId", parent: name, min: 6)
            try self.validate(self.commentId, name: "commentId", parent: name, pattern: "^\\d{6}$")
        }

        private enum CodingKeys: String, CodingKey {
            case body = "body"
        }
    }

    public struct UpdateCaseCommentResponse: AWSDecodableShape {
        /// Response element for UpdateCaseComment providing the updated comment content.
        public let body: String?
        /// Response element for UpdateCaseComment providing the updated comment ID.
        public let commentId: String

        @inlinable
        public init(body: String? = nil, commentId: String) {
            self.body = body
            self.commentId = commentId
        }

        private enum CodingKeys: String, CodingKey {
            case body = "body"
            case commentId = "commentId"
        }
    }

    public struct UpdateCaseRequest: AWSEncodableShape {
        /// Optional element for UpdateCase to provide content for the incident start date field.
        public let actualIncidentStartDate: Date?
        /// Required element for UpdateCase to identify the case ID for updates.
        public let caseId: String
        /// Optional element for UpdateCase to provide content for the description field.
        public let description: String?
        /// Optional element for UpdateCase to provide content for the engagement type field. Available engagement types include Security Incident | Investigation.
        public let engagementType: EngagementType?
        /// Optional element for UpdateCase to provide content to add accounts impacted.
        public let impactedAccountsToAdd: [String]?
        /// Optional element for UpdateCase to provide content to add accounts impacted.
        public let impactedAccountsToDelete: [String]?
        /// Optional element for UpdateCase to provide content to add regions impacted.
        public let impactedAwsRegionsToAdd: [ImpactedAwsRegion]?
        /// Optional element for UpdateCase to provide content to remove regions impacted.
        public let impactedAwsRegionsToDelete: [ImpactedAwsRegion]?
        /// Optional element for UpdateCase to provide content to add services impacted.
        public let impactedServicesToAdd: [String]?
        /// Optional element for UpdateCase to provide content to remove services impacted.
        public let impactedServicesToDelete: [String]?
        /// Optional element for UpdateCase to provide content for the customer reported incident start date field.
        public let reportedIncidentStartDate: Date?
        /// Optional element for UpdateCase to provide content to add additional suspicious IP addresses related to a case.
        public let threatActorIpAddressesToAdd: [ThreatActorIp]?
        /// Optional element for UpdateCase to provide content to remove suspicious IP addresses from a case.
        public let threatActorIpAddressesToDelete: [ThreatActorIp]?
        /// Optional element for UpdateCase to provide content for the title field.
        public let title: String?
        /// Optional element for UpdateCase to provide content to add additional watchers to a case.
        public let watchersToAdd: [Watcher]?
        /// Optional element for UpdateCase to provide content to remove existing watchers from a case.
        public let watchersToDelete: [Watcher]?

        @inlinable
        public init(actualIncidentStartDate: Date? = nil, caseId: String, description: String? = nil, engagementType: EngagementType? = nil, impactedAccountsToAdd: [String]? = nil, impactedAccountsToDelete: [String]? = nil, impactedAwsRegionsToAdd: [ImpactedAwsRegion]? = nil, impactedAwsRegionsToDelete: [ImpactedAwsRegion]? = nil, impactedServicesToAdd: [String]? = nil, impactedServicesToDelete: [String]? = nil, reportedIncidentStartDate: Date? = nil, threatActorIpAddressesToAdd: [ThreatActorIp]? = nil, threatActorIpAddressesToDelete: [ThreatActorIp]? = nil, title: String? = nil, watchersToAdd: [Watcher]? = nil, watchersToDelete: [Watcher]? = nil) {
            self.actualIncidentStartDate = actualIncidentStartDate
            self.caseId = caseId
            self.description = description
            self.engagementType = engagementType
            self.impactedAccountsToAdd = impactedAccountsToAdd
            self.impactedAccountsToDelete = impactedAccountsToDelete
            self.impactedAwsRegionsToAdd = impactedAwsRegionsToAdd
            self.impactedAwsRegionsToDelete = impactedAwsRegionsToDelete
            self.impactedServicesToAdd = impactedServicesToAdd
            self.impactedServicesToDelete = impactedServicesToDelete
            self.reportedIncidentStartDate = reportedIncidentStartDate
            self.threatActorIpAddressesToAdd = threatActorIpAddressesToAdd
            self.threatActorIpAddressesToDelete = threatActorIpAddressesToDelete
            self.title = title
            self.watchersToAdd = watchersToAdd
            self.watchersToDelete = watchersToDelete
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encodeIfPresent(self.actualIncidentStartDate, forKey: .actualIncidentStartDate)
            request.encodePath(self.caseId, key: "caseId")
            try container.encodeIfPresent(self.description, forKey: .description)
            try container.encodeIfPresent(self.engagementType, forKey: .engagementType)
            try container.encodeIfPresent(self.impactedAccountsToAdd, forKey: .impactedAccountsToAdd)
            try container.encodeIfPresent(self.impactedAccountsToDelete, forKey: .impactedAccountsToDelete)
            try container.encodeIfPresent(self.impactedAwsRegionsToAdd, forKey: .impactedAwsRegionsToAdd)
            try container.encodeIfPresent(self.impactedAwsRegionsToDelete, forKey: .impactedAwsRegionsToDelete)
            try container.encodeIfPresent(self.impactedServicesToAdd, forKey: .impactedServicesToAdd)
            try container.encodeIfPresent(self.impactedServicesToDelete, forKey: .impactedServicesToDelete)
            try container.encodeIfPresent(self.reportedIncidentStartDate, forKey: .reportedIncidentStartDate)
            try container.encodeIfPresent(self.threatActorIpAddressesToAdd, forKey: .threatActorIpAddressesToAdd)
            try container.encodeIfPresent(self.threatActorIpAddressesToDelete, forKey: .threatActorIpAddressesToDelete)
            try container.encodeIfPresent(self.title, forKey: .title)
            try container.encodeIfPresent(self.watchersToAdd, forKey: .watchersToAdd)
            try container.encodeIfPresent(self.watchersToDelete, forKey: .watchersToDelete)
        }

        public func validate(name: String) throws {
            try self.validate(self.caseId, name: "caseId", parent: name, max: 32)
            try self.validate(self.caseId, name: "caseId", parent: name, min: 10)
            try self.validate(self.caseId, name: "caseId", parent: name, pattern: "^\\d{10,32}")
            try self.validate(self.description, name: "description", parent: name, max: 8000)
            try self.validate(self.description, name: "description", parent: name, min: 1)
            try self.impactedAccountsToAdd?.forEach {
                try validate($0, name: "impactedAccountsToAdd[]", parent: name, max: 12)
                try validate($0, name: "impactedAccountsToAdd[]", parent: name, min: 12)
                try validate($0, name: "impactedAccountsToAdd[]", parent: name, pattern: "^[0-9]{12}$")
            }
            try self.validate(self.impactedAccountsToAdd, name: "impactedAccountsToAdd", parent: name, max: 200)
            try self.impactedAccountsToDelete?.forEach {
                try validate($0, name: "impactedAccountsToDelete[]", parent: name, max: 12)
                try validate($0, name: "impactedAccountsToDelete[]", parent: name, min: 12)
                try validate($0, name: "impactedAccountsToDelete[]", parent: name, pattern: "^[0-9]{12}$")
            }
            try self.validate(self.impactedAccountsToDelete, name: "impactedAccountsToDelete", parent: name, max: 200)
            try self.validate(self.impactedAwsRegionsToAdd, name: "impactedAwsRegionsToAdd", parent: name, max: 50)
            try self.validate(self.impactedAwsRegionsToDelete, name: "impactedAwsRegionsToDelete", parent: name, max: 50)
            try self.impactedServicesToAdd?.forEach {
                try validate($0, name: "impactedServicesToAdd[]", parent: name, max: 50)
                try validate($0, name: "impactedServicesToAdd[]", parent: name, min: 3)
                try validate($0, name: "impactedServicesToAdd[]", parent: name, pattern: "^[a-zA-Z0-9 -.():]+$")
            }
            try self.validate(self.impactedServicesToAdd, name: "impactedServicesToAdd", parent: name, max: 600)
            try self.impactedServicesToDelete?.forEach {
                try validate($0, name: "impactedServicesToDelete[]", parent: name, max: 50)
                try validate($0, name: "impactedServicesToDelete[]", parent: name, min: 3)
                try validate($0, name: "impactedServicesToDelete[]", parent: name, pattern: "^[a-zA-Z0-9 -.():]+$")
            }
            try self.validate(self.impactedServicesToDelete, name: "impactedServicesToDelete", parent: name, max: 600)
            try self.threatActorIpAddressesToAdd?.forEach {
                try $0.validate(name: "\(name).threatActorIpAddressesToAdd[]")
            }
            try self.validate(self.threatActorIpAddressesToAdd, name: "threatActorIpAddressesToAdd", parent: name, max: 200)
            try self.threatActorIpAddressesToDelete?.forEach {
                try $0.validate(name: "\(name).threatActorIpAddressesToDelete[]")
            }
            try self.validate(self.threatActorIpAddressesToDelete, name: "threatActorIpAddressesToDelete", parent: name, max: 200)
            try self.validate(self.title, name: "title", parent: name, max: 300)
            try self.validate(self.title, name: "title", parent: name, min: 1)
            try self.watchersToAdd?.forEach {
                try $0.validate(name: "\(name).watchersToAdd[]")
            }
            try self.validate(self.watchersToAdd, name: "watchersToAdd", parent: name, max: 30)
            try self.watchersToDelete?.forEach {
                try $0.validate(name: "\(name).watchersToDelete[]")
            }
            try self.validate(self.watchersToDelete, name: "watchersToDelete", parent: name, max: 30)
        }

        private enum CodingKeys: String, CodingKey {
            case actualIncidentStartDate = "actualIncidentStartDate"
            case description = "description"
            case engagementType = "engagementType"
            case impactedAccountsToAdd = "impactedAccountsToAdd"
            case impactedAccountsToDelete = "impactedAccountsToDelete"
            case impactedAwsRegionsToAdd = "impactedAwsRegionsToAdd"
            case impactedAwsRegionsToDelete = "impactedAwsRegionsToDelete"
            case impactedServicesToAdd = "impactedServicesToAdd"
            case impactedServicesToDelete = "impactedServicesToDelete"
            case reportedIncidentStartDate = "reportedIncidentStartDate"
            case threatActorIpAddressesToAdd = "threatActorIpAddressesToAdd"
            case threatActorIpAddressesToDelete = "threatActorIpAddressesToDelete"
            case title = "title"
            case watchersToAdd = "watchersToAdd"
            case watchersToDelete = "watchersToDelete"
        }
    }

    public struct UpdateCaseResponse: AWSDecodableShape {
        public init() {}
    }

    public struct UpdateCaseStatusRequest: AWSEncodableShape {
        /// Required element for UpdateCaseStatus to identify the case to update.
        public let caseId: String
        /// Required element for UpdateCaseStatus to identify the status for a case. Options include Submitted | Detection and Analysis | Containment, Eradication and Recovery | Post-incident Activities.
        public let caseStatus: SelfManagedCaseStatus

        @inlinable
        public init(caseId: String, caseStatus: SelfManagedCaseStatus) {
            self.caseId = caseId
            self.caseStatus = caseStatus
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.caseId, key: "caseId")
            try container.encode(self.caseStatus, forKey: .caseStatus)
        }

        public func validate(name: String) throws {
            try self.validate(self.caseId, name: "caseId", parent: name, max: 32)
            try self.validate(self.caseId, name: "caseId", parent: name, min: 10)
            try self.validate(self.caseId, name: "caseId", parent: name, pattern: "^\\d{10,32}")
        }

        private enum CodingKeys: String, CodingKey {
            case caseStatus = "caseStatus"
        }
    }

    public struct UpdateCaseStatusResponse: AWSDecodableShape {
        /// Response element for UpdateCaseStatus showing the newly configured status.
        public let caseStatus: SelfManagedCaseStatus?

        @inlinable
        public init(caseStatus: SelfManagedCaseStatus? = nil) {
            self.caseStatus = caseStatus
        }

        private enum CodingKeys: String, CodingKey {
            case caseStatus = "caseStatus"
        }
    }

    public struct UpdateMembershipRequest: AWSEncodableShape {
        /// Optional element for UpdateMembership to update the membership name.
        public let incidentResponseTeam: [IncidentResponder]?
        /// Required element for UpdateMembership to identify the membership to update.
        public let membershipId: String
        /// Optional element for UpdateMembership to update the membership name.
        public let membershipName: String?
        /// Optional element for UpdateMembership to enable or disable opt-in features for the service.
        public let optInFeatures: [OptInFeature]?

        @inlinable
        public init(incidentResponseTeam: [IncidentResponder]? = nil, membershipId: String, membershipName: String? = nil, optInFeatures: [OptInFeature]? = nil) {
            self.incidentResponseTeam = incidentResponseTeam
            self.membershipId = membershipId
            self.membershipName = membershipName
            self.optInFeatures = optInFeatures
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encodeIfPresent(self.incidentResponseTeam, forKey: .incidentResponseTeam)
            request.encodePath(self.membershipId, key: "membershipId")
            try container.encodeIfPresent(self.membershipName, forKey: .membershipName)
            try container.encodeIfPresent(self.optInFeatures, forKey: .optInFeatures)
        }

        public func validate(name: String) throws {
            try self.incidentResponseTeam?.forEach {
                try $0.validate(name: "\(name).incidentResponseTeam[]")
            }
            try self.validate(self.incidentResponseTeam, name: "incidentResponseTeam", parent: name, max: 10)
            try self.validate(self.incidentResponseTeam, name: "incidentResponseTeam", parent: name, min: 2)
            try self.validate(self.membershipId, name: "membershipId", parent: name, max: 34)
            try self.validate(self.membershipId, name: "membershipId", parent: name, min: 12)
            try self.validate(self.membershipId, name: "membershipId", parent: name, pattern: "^m-[a-z0-9]{10,32}$")
            try self.validate(self.membershipName, name: "membershipName", parent: name, max: 50)
            try self.validate(self.membershipName, name: "membershipName", parent: name, min: 3)
            try self.validate(self.optInFeatures, name: "optInFeatures", parent: name, max: 2)
            try self.validate(self.optInFeatures, name: "optInFeatures", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case incidentResponseTeam = "incidentResponseTeam"
            case membershipName = "membershipName"
            case optInFeatures = "optInFeatures"
        }
    }

    public struct UpdateMembershipResponse: AWSDecodableShape {
        public init() {}
    }

    public struct UpdateResolverTypeRequest: AWSEncodableShape {
        /// Required element for UpdateResolverType to identify the case to update.
        public let caseId: String
        /// Required element for UpdateResolverType to identify the new resolver.
        public let resolverType: ResolverType

        @inlinable
        public init(caseId: String, resolverType: ResolverType) {
            self.caseId = caseId
            self.resolverType = resolverType
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.caseId, key: "caseId")
            try container.encode(self.resolverType, forKey: .resolverType)
        }

        public func validate(name: String) throws {
            try self.validate(self.caseId, name: "caseId", parent: name, max: 32)
            try self.validate(self.caseId, name: "caseId", parent: name, min: 10)
            try self.validate(self.caseId, name: "caseId", parent: name, pattern: "^\\d{10,32}")
        }

        private enum CodingKeys: String, CodingKey {
            case resolverType = "resolverType"
        }
    }

    public struct UpdateResolverTypeResponse: AWSDecodableShape {
        /// Response element for UpdateResolver identifying the case ID being updated.
        public let caseId: String
        /// Response element for UpdateResolver identifying the current status of the case.
        public let caseStatus: CaseStatus?
        /// Response element for UpdateResolver identifying the current resolver of the case.
        public let resolverType: ResolverType?

        @inlinable
        public init(caseId: String, caseStatus: CaseStatus? = nil, resolverType: ResolverType? = nil) {
            self.caseId = caseId
            self.caseStatus = caseStatus
            self.resolverType = resolverType
        }

        private enum CodingKeys: String, CodingKey {
            case caseId = "caseId"
            case caseStatus = "caseStatus"
            case resolverType = "resolverType"
        }
    }

    public struct ValidationException: AWSErrorShape {
        /// Element that provides the list of field(s) that caused the error, if applicable.
        public let fieldList: [ValidationExceptionField]?
        public let message: String
        /// Element that provides the reason the request failed validation.
        public let reason: ValidationExceptionReason

        @inlinable
        public init(fieldList: [ValidationExceptionField]? = nil, message: String, reason: ValidationExceptionReason) {
            self.fieldList = fieldList
            self.message = message
            self.reason = reason
        }

        private enum CodingKeys: String, CodingKey {
            case fieldList = "fieldList"
            case message = "message"
            case reason = "reason"
        }
    }

    public struct ValidationExceptionField: AWSDecodableShape {
        public let message: String
        public let name: String

        @inlinable
        public init(message: String, name: String) {
            self.message = message
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
            case name = "name"
        }
    }

    public struct Watcher: AWSEncodableShape & AWSDecodableShape {
        public let email: String
        public let jobTitle: String?
        public let name: String?

        @inlinable
        public init(email: String, jobTitle: String? = nil, name: String? = nil) {
            self.email = email
            self.jobTitle = jobTitle
            self.name = name
        }

        public func validate(name: String) throws {
            try self.validate(self.email, name: "email", parent: name, max: 254)
            try self.validate(self.email, name: "email", parent: name, min: 6)
            try self.validate(self.email, name: "email", parent: name, pattern: "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$")
            try self.validate(self.jobTitle, name: "jobTitle", parent: name, max: 50)
            try self.validate(self.jobTitle, name: "jobTitle", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, max: 50)
            try self.validate(self.name, name: "name", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case email = "email"
            case jobTitle = "jobTitle"
            case name = "name"
        }
    }
}

// MARK: - Errors

/// Error enum for SecurityIR
public struct SecurityIRErrorType: AWSErrorType {
    enum Code: String {
        case accessDeniedException = "AccessDeniedException"
        case conflictException = "ConflictException"
        case internalServerException = "InternalServerException"
        case invalidTokenException = "InvalidTokenException"
        case resourceNotFoundException = "ResourceNotFoundException"
        case securityIncidentResponseNotActiveException = "SecurityIncidentResponseNotActiveException"
        case serviceQuotaExceededException = "ServiceQuotaExceededException"
        case throttlingException = "ThrottlingException"
        case validationException = "ValidationException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize SecurityIR
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    public static var accessDeniedException: Self { .init(.accessDeniedException) }
    public static var conflictException: Self { .init(.conflictException) }
    public static var internalServerException: Self { .init(.internalServerException) }
    public static var invalidTokenException: Self { .init(.invalidTokenException) }
    public static var resourceNotFoundException: Self { .init(.resourceNotFoundException) }
    /// API Reference: https://docs.aws.amazon.com/security-ir/latest/APIReference/CommonErrors.html
    public static var securityIncidentResponseNotActiveException: Self { .init(.securityIncidentResponseNotActiveException) }
    public static var serviceQuotaExceededException: Self { .init(.serviceQuotaExceededException) }
    public static var throttlingException: Self { .init(.throttlingException) }
    public static var validationException: Self { .init(.validationException) }
}

extension SecurityIRErrorType: AWSServiceErrorType {
    public static let errorCodeMap: [String: AWSErrorShape.Type] = [
        "ValidationException": SecurityIR.ValidationException.self
    ]
}

extension SecurityIRErrorType: Equatable {
    public static func == (lhs: SecurityIRErrorType, rhs: SecurityIRErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension SecurityIRErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
